import os
import time
import psutil
from datetime import datetime
from utils.logger import get_logger, INFO

# 创建系统监控专用的日志器
logger = get_logger("system_monitor", level=INFO, daily_rotation=True)

class SystemMonitor:
    """系统监控类，用于收集和记录服务器状态信息"""
    
    def __init__(self, interval=60):
        """初始化系统监控器
        
        Args:
            interval: 监控间隔，单位为秒，默认60秒
        """
        self.interval = interval
        self.is_running = False
        self.job_id = 'system_status_job'
    
    def start(self, scheduler=None):
        """启动系统监控
        
        Args:
            scheduler: 调度器实例，如果为None则不会自动注册任务
        """
        if not self.is_running and scheduler:
            # 添加定时任务，按指定间隔记录系统状态
            scheduler.add_job(
                self.log_system_status,
                'interval',
                seconds=self.interval,
                id=self.job_id
            )
            
            self.is_running = True
            logger.info(f"系统监控已启动，监控间隔: {self.interval}秒")
    
    def stop(self, scheduler=None):
        """停止系统监控
        
        Args:
            scheduler: 调度器实例，如果为None则不会自动注销任务
        """
        if self.is_running and scheduler:
            scheduler.remove_job(self.job_id)
            self.is_running = False
            logger.info("系统监控已停止")
    
    def log_system_status(self):
        """记录系统状态信息"""
        try:
            # 获取CPU使用率
            cpu_percent = psutil.cpu_percent(interval=1)
            
            # 获取内存使用情况
            memory = psutil.virtual_memory()
            memory_percent = memory.percent
            memory_used = self._format_bytes(memory.used)
            memory_total = self._format_bytes(memory.total)
            
            # 获取磁盘使用情况
            disk = psutil.disk_usage('/')
            disk_percent = disk.percent
            disk_used = self._format_bytes(disk.used)
            disk_total = self._format_bytes(disk.total)
            
            # 获取网络IO统计
            net_io = psutil.net_io_counters()
            net_sent = self._format_bytes(net_io.bytes_sent)
            net_recv = self._format_bytes(net_io.bytes_recv)
            
            # 获取进程数量
            process_count = len(psutil.pids())
            
            # 获取系统启动时间
            boot_time = datetime.fromtimestamp(psutil.boot_time()).strftime('%Y-%m-%d %H:%M:%S')
            
            # 记录系统状态日志
            status_info = (
                f"系统状态报告 | "
                f"CPU: {cpu_percent}% | "
                f"内存: {memory_used}/{memory_total} ({memory_percent}%) | "
                f"磁盘: {disk_used}/{disk_total} ({disk_percent}%) | "
                f"网络: 发送 {net_sent}, 接收 {net_recv} | "
                f"进程数: {process_count} | "
                f"系统启动时间: {boot_time}"
            )
            
            logger.info(status_info)
            
        except Exception as e:
            logger.error(f"记录系统状态时出错: {str(e)}", exc_info=True)
    
    @staticmethod
    def _format_bytes(bytes_value):
        """将字节数格式化为人类可读的形式
        
        Args:
            bytes_value: 字节数
            
        Returns:
            str: 格式化后的字符串，如 '1.23 GB'
        """
        for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
            if bytes_value < 1024.0:
                return f"{bytes_value:.2f} {unit}"
            bytes_value /= 1024.0
        return f"{bytes_value:.2f} PB"


# 创建默认的系统监控器实例
_default_monitor = None
# 标记监控器是否已启动，用于防止在Flask debug模式下重复启动
_monitor_started = False


def get_monitor(interval=60):
    """获取系统监控器实例
    
    Args:
        interval: 监控间隔，单位为秒，默认60秒
        
    Returns:
        SystemMonitor: 系统监控器实例
    """
    global _default_monitor
    if _default_monitor is None:
        _default_monitor = SystemMonitor(interval=interval)
    return _default_monitor


def start_monitoring(interval=60, scheduler=None):
    """启动系统监控
    
    Args:
        interval: 监控间隔，单位为秒，默认60秒
        scheduler: 调度器实例，如果为None则尝试从scheduler模块获取
        
    Returns:
        SystemMonitor: 系统监控器实例
    """
    global _monitor_started
    
    # 如果没有提供调度器，尝试从scheduler模块获取
    if scheduler is None:
        try:
            from utils.scheduler import get_scheduler
            scheduler = get_scheduler()
        except ImportError:
            logger.error("无法导入调度器模块，系统监控无法启动")
            return None
    
    # 检查监控器是否已经启动，避免在Flask debug模式下重复启动
    if _monitor_started:
        logger.info("系统监控已经在运行中，跳过重复启动")
        return get_monitor(interval)
    
    monitor = get_monitor(interval)
    monitor.start(scheduler)
    _monitor_started = True
    return monitor


def stop_monitoring(scheduler=None):
    """停止系统监控
    
    Args:
        scheduler: 调度器实例，如果为None则尝试从scheduler模块获取
    """
    global _default_monitor
    
    # 如果没有提供调度器，尝试从scheduler模块获取
    if scheduler is None and _default_monitor is not None:
        try:
            from utils.scheduler import get_scheduler
            scheduler = get_scheduler()
        except ImportError:
            logger.error("无法导入调度器模块，系统监控无法停止")
            return
    
    if _default_monitor is not None:
        _default_monitor.stop(scheduler)
